#pragma once
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cctype>
#include <unordered_map>
#include <iomanip>
using namespace std;
// Token 类型定义
enum class TokenType {
    // 关键字
    INT,
    VOID,
    IF,
    ELSE,
    WHILE,
    BREAK,
    CONTINUE,
    RETURN,

    // 标识符和字面量
    IDENTIFIER,
    NUMBER,

    // 运算符
    ASSIGN,         // =
    OR,             // ||
    AND,            // &&
    LT, GT, LE, GE, // < > <= >=
    EQ, NE,         // == !=
    ADD, SUB,       // + -
    MUL, DIV, MOD,  // * / %
    NOT,            // !

    // 分隔符
    COMMA,          // ,
    SEMICOLON,      // ;
    LPAREN,         // (
    RPAREN,         // )
    LBRACE,         // {
    RBRACE,         // }

    // 特殊标记
    END_OF_FILE,    // 文件结束
    UNKNOWN         // 未知字符
};

// Token 结构体
struct Token {
    TokenType type;     // Token 类型
    std::string lexeme; // 词素内容
    int line;           // 行号（第一个字符）
    int column;         // 列号（第一个字符）

    Token(TokenType t, const std::string& l, int ln, int col)
        : type(t), lexeme(l), line(ln), column(col) {
    }
};

// 词法分析器类
class Lexer {
public:
    Lexer(const std::string& source);
    vector<Token> tokenize();
    const std::vector<std::string>& getErrors() const { return errors; }

private:
    string source;        // 源代码字符串
    size_t position;           // 当前位置
    int line;                  // 当前行号
    int column;                // 当前列号
    std::unordered_map<std::string, TokenType> keywords; // 关键字映射
    std::vector<std::string> errors; // 错误信息收集

    // 前进一个字符
    void advance();

    // 查看当前字符（不前进位置）
    char peek();

    // 查看下一个字符（不前进位置）
    char peekNext();

    // 跳过空白字符（包括空格、制表符、换行符等）
    void skipWhitespace();

    // 跳过单行注释
    void skipLineComment();

    // 跳过多行注释
    void skipBlockComment();

    // 处理注释
    void handleComments();

    // 解析标识符或关键字
    Token parseIdentifierOrKeyword();

    // 解析数字（支持负号）
    Token parseNumber();

    // 解析运算符
    Token parseOperator();

    // 获取下一个Token
    Token getNextToken();

    // 解析分隔符
    Token parseDelimiter();

};

// 打印Token列表
void printTokens(const std::vector<Token>& tokens);

